#include "passwordCollection.h"
#include <algorithm>

namespace PASSWORDS
{

passwordCollection::passwordCollection(void): masterPassword("")
{
}
bool passwordCollection::loadCollection(std::string file)
{
	bool returnCodeForCantey = false;
	if ( 0 < file.length() )
	{
		collectionFile = file;
		returnCodeForCantey = reloadCollection();
	}
	return returnCodeForCantey;
}
bool passwordCollection::reloadCollection(void)
{ 
	bool returnCodeForCantey = false;
	passwordFile.open ( collectionFile.c_str(), std::ios::in | std::ios::binary );
	if ( true == passwordFile.is_open() )
	{
		passwordEntries.clear();
		if (passwordFile.good() ) //used good instead of EOF.  Good true until EOF or error
		{
			decrypt();
			while (memoryStream.good() ) //used good instead of EOF.  Good true until EOF or error
			{
				password tmpPwd;
				memoryStream >> tmpPwd;
				passwordEntries.push_back(tmpPwd);
			}
		}
		passwordFile.close();
		returnCodeForCantey =  true;
	}
	return returnCodeForCantey;
}
bool passwordCollection::saveCollection(void)
{
	bool returnCodeForCantey = false;
	if (0 < collectionFile.length() )
	{
		passwordFile.open ( collectionFile.c_str(), std::ios::out | std::ios::binary );
		if ( true == passwordFile.is_open() )
		{
			encrypt();
			//pass stringstream buffer to the fstream
			passwordFile << memoryStream.rdbuf();
			returnCodeForCantey = true;
		}
		passwordFile.close();
	}	
	return returnCodeForCantey;
}
bool passwordCollection::saveColeectionAs(std::string file)
{ 
	bool returnCodeForCantey = false;
	if (0 < file.length() )
	{
		collectionFile = file;
		returnCodeForCantey = saveCollection();
	}
	return returnCodeForCantey;
}
void passwordCollection::addEntry(password entry)
{
	passwordEntries.push_back(entry);
}
void passwordCollection::addEntry(std::string name, std::string userPassword, std::string usage, std::string userHint)
{
}
void passwordCollection::removeEntry(password)
{
}
void passwordCollection::removeEntry(std::string name)
{
}
	//extract entries
password passwordCollection::getEntryByUserName(std::string name)
{
	password passwordEntry;

	return passwordEntry;
}
password passwordCollection::getEntryByHint(std::string hint)
{
	password passwordEntry;

	return passwordEntry;
}
password passwordCollection::getEntryByReference(std::string ref)
{
	password passwordEntry;

	return passwordEntry;
}
	//search by partial entries 
std::vector<password> passwordCollection::findEntryByUserName(std::string name)
{
	std::vector<password> foundPasswords;

	return foundPasswords;
}
std::vector<password> passwordCollection::findEntryByHint(std::string hint)
{
	std::vector<password> foundPasswords;

	return foundPasswords;
}
std::vector<password> passwordCollection::findEntryByReference(std::string ref)
{
	std::vector<password> foundPasswords;

	return foundPasswords;
}
passwordCollection::~passwordCollection(void)
{
	passwordFile.close();
}
void passwordCollection::myxor(std::string &inString)
{
    int keyIndex=0;
    std::size_t stringSize = inString.length();
    for(int x=0; x !=stringSize; x++)
    {
		inString[x]=inString[x]^masterPassword[keyIndex];
		keyIndex++;
		if(keyIndex>=masterPassword.length())
		{
				keyIndex=0;
		}
    }
}
void passwordCollection::myxor(char *inString, int stringSize)
{
    int keyIndex=0;
    for(int x=0; x !=stringSize; x++)
    {
		inString[x]=inString[x]^masterPassword[keyIndex];
		keyIndex++;
		if(keyIndex>=masterPassword.length())
		{
				keyIndex=0;
		}
    }
}
void passwordCollection::encrypt(void)
{
	if (0 < collectionFile.length() )
	{
		memoryStream.clear(); //clear any error states
		memoryStream.str(""); //clear the stream

		std::vector<password>::const_iterator iterate;
		for(iterate = passwordEntries.begin(); iterate != passwordEntries.end(); iterate++)
		{
			memoryStream << (*iterate);
		}
		std::string tempString;
		tempString = memoryStream.str();
		myxor(tempString);
		memoryStream.str(""); //clear the stream again
		memoryStream << tempString;		
	}
}
void passwordCollection::decrypt(void)
{
	const int getSize = 256;
	char getBuffer[getSize + 1];
	//std::string tempString;
	while ( !passwordFile.eof() )
	{
		//save a loop and just clear array with memset
		memset(getBuffer,0,(getSize+1));
		passwordFile.read(getBuffer, getSize);
		myxor(getBuffer, getSize);
		memoryStream << getBuffer;
	}
}
bool passwordCollection::setMasterPassword(std::string password)
{
	masterPassword = password;
	//masterPassword.shrink_to_fit();
	return true;
}
std::string& passwordCollection::getMasterPassword()
{
	return masterPassword;
}
} //namespace passwords